/*
 * Copyright 2013-2018 Lilinfeng.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package main.java.com.waylau.netty.demo.privateprotocol.client;

import com.alibaba.fastjson.JSON;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import main.java.com.waylau.netty.demo.privateprotocol.struct.Header;
import main.java.com.waylau.netty.demo.privateprotocol.struct.NettyMessage;
import main.java.com.waylau.netty.demo.privateprotocol.util.MessageType;
import main.java.com.waylau.netty.demo.privateprotocol.util.NettyConstant;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author Lilinfeng
 * @date 2014年3月15日
 * @version 1.0
 */
public class NettyClient {

	private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
	EventLoopGroup group = new NioEventLoopGroup();

	public void connect(int port, String host) throws Exception {
		// 配置客户端NIO线程组
		try {
			Bootstrap b = new Bootstrap();
			b.group(group)
					.channel(NioSocketChannel.class)
					.option(ChannelOption.TCP_NODELAY, true)
					.handler(new NettyClientInitializer());
//					.handler(new NettyClientInitializer(SSLMODE.CSA.toString()));
			// 发起异步连接操作
			ChannelFuture future = b.connect(host,port).sync();
			// 这里指定 客户端的地址和端口的话 会导致重连失败
//			ChannelFuture future = b.connect(new InetSocketAddress(host, port), new InetSocketAddress(NettyConstant.LOCALIP, NettyConstant.LOCAL_PORT)).sync();

//			像客服务器发送数据
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
			while (true){
				String str=bufferedReader.readLine();
				NettyMessage nettyMessage = new NettyMessage();
				Header header=new Header();
				header.setType(MessageType.SERVICE_REQ.value());
				nettyMessage.setHeader(header);
				nettyMessage.setBody(str);
//				这里不能直接发送对象；必须转成String去发送
				future.channel().writeAndFlush(JSON.toJSONString(nettyMessage));
				System.out.println("发送："+nettyMessage.toString());
			}



//			future.channel().closeFuture().sync();
//
//			System.out.println("客户端关闭");
		} finally {
			// 所有资源释放完成之后，清空资源，再次发起重连操作
			executor.execute(new Runnable() {
				@Override
				public void run() {
					try {
						TimeUnit.SECONDS.sleep(1);
						try {
							System.out.println("发起重连:run");
							connect(NettyConstant.PORT, NettyConstant.REMOTEIP);// 发起重连操作
						} catch (Exception e) {
							e.printStackTrace();
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});

		}
	}

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		new NettyClient().connect(NettyConstant.PORT, NettyConstant.REMOTEIP);
	}

}
